package com.corpdata.app.customer.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;

import com.alibaba.fastjson.JSON;
import com.corpdata.app.customer.dao.CustomerInfoMapper;
import com.corpdata.app.customer.dao.RecommendRecordMapper;
import com.corpdata.app.customer.dao.SellRecordMapper;
import com.corpdata.app.customer.dao.SellTeamStaffMapper;
import com.corpdata.app.customer.dao.VisitRecordMapper;
import com.corpdata.app.customer.entity.CustomerInfo;
import com.corpdata.app.customer.entity.RecommendRecord;
import com.corpdata.app.customer.entity.SellRecord;
import com.corpdata.app.customer.entity.SellTeamStaff;
import com.corpdata.app.customer.entity.VisitRecord;
import com.corpdata.app.customer.service.CustomerInfoService;
import com.corpdata.app.project.dao.ProjectInfoMapper;
import com.corpdata.app.project.dao.ProjectPartitionMapper;
import com.corpdata.common.api.pagehelper.PageConvertUtil;
import com.corpdata.common.domain.DataGridRequestDTO;
import com.corpdata.common.result.Result;
import com.corpdata.common.utils.CorpdataUtil;
import com.corpdata.common.utils.DateUtils;
import com.corpdata.core.base.AbstractBaseService;
import com.corpdata.system.log.OptLog;
import com.corpdata.system.log.OptLogConstant;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

/**
 * 客户表
 * 
 * @author wu
 * @email 64088839@qq.com
 * @date 2018-06-13 16:46:46
 */
@Service
@Transactional
public class CustomerInfoServiceImpl extends AbstractBaseService<CustomerInfo> implements CustomerInfoService {

	@Autowired
	private SellTeamStaffMapper sellTeamStaffMapper;//销售团队人员
	
	@Autowired
	private ProjectInfoMapper projectInfoMapper;//分店
	
	@Autowired
	private VisitRecordMapper visitRecordMapper;//参观记录
	
	@Autowired
	private SellRecordMapper sellRecordMapper;//销售记录
	
	@Autowired
	private CustomerInfoMapper customerInfoMapper;
	
	@Autowired
	private ProjectPartitionMapper projectPartitionMapper;//分区
	
	@Autowired
	private RecommendRecordMapper recommendRecordMapper;//推荐房间
	
	private final Logger log=LoggerFactory.getLogger(CustomerInfoServiceImpl.class);
	
	/**
	 * 保存客户 包括关联表的信息
	 * 销售记录的状态有三种，三种的字段略有不同，
	 * 表单采用了隐藏字段的方式来展示不同状态对应的字段，为了方便封装没有考虑状态进行字段封装
	 * 也就是如果客户填了状态2所需字段然后又切回到状态1，那么表中数据状态为1 对应的字段会包括状态2的字段值 当然状态2对应的这些字段值是无效的 
	 * @param record
	 * @return
	 */
	@Override
	@OptLog(module=OptLogConstant.MODULE_CUSTOMER,info=OptLogConstant.INFO_ADD)
	public Result addCustomer(Map<String,String> param) {
		Date now=new Date();
		String cusJson=param.get("cusJson").replaceAll("&quot;", "\"");//配置了防xss 所以需要在转回来(转换双引号),客户
		CustomerInfo ci=JSON.parseObject(cusJson, CustomerInfo.class);//客户数据
		ci.setId(CorpdataUtil.getUUID());//设置客户id
		ci.setCreated(now);
		ci.getSellRecord().setId(CorpdataUtil.getUUID());//设置销售记录id
		ci.getSellRecord().setFkCustomer(ci.getId());//设置销售记录客户外键
		ci.getSellRecord().setCreated(now);//设置销售记录创建时间
		ci.getSellRecord().setOnUse(1);//默认为当前可用
		String ts=param.get("teamStaff").replaceAll("&quot;", "\"");//配置了防xss 所以需要在转回来(转换双引号),销售团队人员
		
		String visitList=null;
		if(ci.getSellRecord().getVisit()==0) {//已参观
			visitList=param.get("visitList").replaceAll("&quot;", "\"");//参观数据
		}else if(ci.getSellRecord().getVisit()==1) {//预约参观
			//预约参观也放到参观记录中，不同的是预约参观只有一个预约时间 没有其他数据 所以要分开处理
			visitList="[{visitDate:\""+ci.getSubVisitDate()+"\"}]";
		}
		int r=customerInfoMapper.insert(ci);
		log.info("客户插入{}条",r);
		if(r>0) {
			//销售团队部分
			if(ts!=null&&!ts.equals("")) {
				String[] teamStaff=ts.split(",");
				SellTeamStaff[] sts=teamStaffPack(teamStaff,ci.getId());//销售团队人员
				if(sts.length>0) {//插入销售团队
					r = sellTeamStaffMapper.insertList(sts);
					log.info("客户对应销售团队插入{}条",r);
				}
			}
			//销售记录部分
			r=sellRecordMapper.insert(ci.getSellRecord());
			log.info("销售记录插入{}条",r);
			//参观记录部分 与销售记录有关联
			List<VisitRecord> vrs=visitRecordPack(visitList,ci);//参观数据
			if(vrs!=null&&vrs.size()>0) {//插入参观数据
				r = visitRecordMapper.insertList(vrs);
				log.info("参观记录插入{}条",r);
			}
		}
		return new Result(1, "保存成功");
	}
	
	private List<VisitRecord> visitRecordPack(String visitList, CustomerInfo ci) {
		List<VisitRecord> vrs=JSON.parseArray(visitList, VisitRecord.class);
		if(vrs!=null) {
			for (VisitRecord vr : vrs) {
				vr.setId(CorpdataUtil.getUUID());
				vr.setFkCustomer(ci.getId());
				vr.setFkSellRecord(ci.getSellRecord().getId());
				vr.setCreated(ci.getSellRecord().getCreated());
			}
		}
		return vrs;
	}

	/**
	 * 封装销售团队人员
	 * @param teamStaff
	 * @return 
	 */
	private SellTeamStaff[] teamStaffPack(String[] teamStaff,String cusId) {
		SellTeamStaff[] sts=new SellTeamStaff[teamStaff.length];
		for (int i=0;i<sts.length; i++) {
			SellTeamStaff sell = new SellTeamStaff();
			sell.setId(CorpdataUtil.getUUID());
			sell.setFkCustomerInfo(cusId);
			sell.setFkUser(teamStaff[i]);
			sts[i]=sell;
		}
		return sts;
	}
	
	/**
	 * 获取所有分店信息 格式符合select下拉(id，text)
	 * @return
	 */
	@Override
	public List<Map<String,String>> getProjectJson() {
		return projectInfoMapper.getProjectJson();
	}

	@Override
	public String findByPage(DataGridRequestDTO dgRequest) {
		PageHelper.startPage(dgRequest.getPage(), dgRequest.getLimit());
		Map<String,Object> params=dgRequest.getParams();
		if(params!=null) {//条件处理
			//赢单分店
			if(params.get("projectId")!=null&&params.get("projectId").toString().length()>=32) {//需要够一个id的长度
				params.put("projectId",params.get("projectId").toString().split(","));
			}else {
				params.remove("projectId");
			}
			//负责人
			if(params.get("executor")!=null&&params.get("executor").equals(""))params.remove("executor");
			//状态
			if(params.get("customerStatus")!=null&&params.get("customerStatus").equals(""))params.remove("customerStatus");
			//来源
			if(params.get("customerSource")!=null&&params.get("customerSource").equals(""))params.remove("customerSource");
			//客户名称
			if(params.get("customerName")!=null&&params.get("customerName").equals(""))params.remove("customerName");
		}
		Page<CustomerInfo> list = customerInfoMapper.selectAllExt(params);
		return PageConvertUtil.getGridJson(list);
	}

	/**
	 * 根据条件查询查询,可分页
	 */
	@Override
	public Page<SellRecord> findsellRecord(DataGridRequestDTO dgRequest) {
		if(dgRequest.getLimit()!=0&&dgRequest.getPage()!=0) {
			PageHelper.startPage(dgRequest.getPage(),dgRequest.getLimit());
		}
		return sellRecordMapper.selectBycIdAnduId(dgRequest.getParams());
	}
	@Override
	public Page<SellRecord> findsellRecordBycIdAnduId(String cid) {
		Map<String,Object> params=new HashMap<String,Object>();
		params.put("cId", cid);
		return findsellRecord(new DataGridRequestDTO(0,0, params));
	}

	/**
	 * 根据客户id获取参观记录信息
	 */
	@Override
	public String findVisitByPage(DataGridRequestDTO dgRequest) {
		PageHelper.startPage(dgRequest.getPage(), dgRequest.getLimit());
		Page<VisitRecord> list = (Page<VisitRecord>)visitRecordMapper.selectAll(dgRequest.getParams());
		return PageConvertUtil.getGridJson(list);
	}

	@Override
	public CustomerInfo findEdit(String id) {
		return customerInfoMapper.selectEdit(id);
	}

	/**
	 * 编辑客户
	 */
	@Override
	@OptLog(module=OptLogConstant.MODULE_CUSTOMER,info=OptLogConstant.INFO_MOF)
	public Result editCustomer(Map<String, String> param) {
		String cusJson=param.get("cusJson").replaceAll("&quot;", "\"");//配置了防xss 所以需要在转回来(转换双引号),客户
		CustomerInfo ci=JSON.parseObject(cusJson, CustomerInfo.class);//客户数据,id由页面传过来
		String ts=param.get("teamStaff").replaceAll("&quot;", "\"");//待新增的销售团队人员,配置了防xss 所以需要在转回来(转换双引号)
		
		int r=mapper.update(ci);
		log.info("客户修改{}条",r);
		if(r>0) {
			//销售团队部分,销售团队人员的编辑也就是先全部删除在从新增加
			if(ts!=null&&!ts.equals("")) {//新增销售团队
				String[] teamStaff=ts.split(",");
				SellTeamStaff[] sts=teamStaffPack(teamStaff,ci.getId());//销售团队人员
				if(sts.length>0) {//新增销售团队
					r=sellTeamStaffMapper.deleteAllByCid(ci.getId());
					log.info("客户对应销售团队删除{}条",r);
					r = sellTeamStaffMapper.insertList(sts);
					log.info("客户对应销售团队重新增加{}条",r);
				}
			}
		}
		return new Result(1, "编辑成功");
	}

	@Override
	public SellRecord findsellRecordById(String cid) {
		return sellRecordMapper.selectExt(cid);
	}

	/**
	 * 更新销售记录+参观记录  所谓的更新就是在该客户上在增加一条数据 每个客户可以有多个销售记录 
	 * 查看的时候取最新的  其他的作为历史记录保留
	 */
	@Override
	@OptLog(module=OptLogConstant.MODULE_CUSTOMER,info=OptLogConstant.INFO_UPD_STATE)
	public Result updateCustomerStaus(Map<String, String> param) {
		String srJson=param.get("srJson").replaceAll("&quot;", "\"");//配置了防xss 所以需要在转回来(转换双引号),销售记录
		SellRecord sr=JSON.parseObject(srJson, SellRecord.class);//销售记录
		sr.setId(CorpdataUtil.getUUID());
		sr.setOnUse(1);
		sr.setCreated(new Date());
		
		//推荐房间
		String recommendJson = param.get("roomList").replaceAll("&quot;", "\"");
		List<RecommendRecord> recommendList=JSON.parseArray(recommendJson, RecommendRecord.class);
		
		String visitList=null;
		if(sr.getVisit()==0) {//已参观
			visitList=param.get("visitList").replaceAll("&quot;", "\"");//参观数据
		}else if(sr.getVisit()==1) {//预约参观
			//预约参观也放到参观记录中，不同的是预约参观只有一个预约时间 没有其他数据 所以要分开处理
			visitList="[{visitDate:\""+DateUtils.format(sr.getSubVisitDate())+"\"}]";
		}
		//销售记录部分
		sellRecordMapper.updateBycId(sr.getFkCustomer());//插入之前先将其他的修改为非使用态
		int r=sellRecordMapper.insert(sr);
		log.info("销售记录插入{}条",r);
		if(visitList!=null) {
			//参观记录部分 与销售记录有关联
			List<VisitRecord> vrs=visitRecordPack(visitList,sr);//参观数据
			if(vrs!=null&&vrs.size()>0) {//插入参观数据
				r = visitRecordMapper.insertList(vrs);
				log.info("参观记录插入{}条",r);
			}
		}
		//推荐房间部分
		if(recommendList!=null&&recommendList.size()>0) {
			recommendProcess(recommendList,sr);//包装一下 赋值主键啥的
			//recommendRecordMapper.deleteByFkCustomer(sr.getFkCustomer());  //根据客户删除推荐记录 以保证一个客户只有一批推荐记录
			r=recommendRecordMapper.insertList(recommendList);
			log.info("推荐房间插入{}条",r);
		}
		return new Result(1, "发布成功");
	}
	private void recommendProcess(List<RecommendRecord> recommendList,SellRecord sr) {
		Date now = new Date();
		for (RecommendRecord rr : recommendList) {
			rr.setId(CorpdataUtil.getUUID());
			rr.setFkSellRecord(sr.getId());
			rr.setFkCustomer(sr.getFkCustomer());
			rr.setCreated(now);
		}
	}
	
	private List<VisitRecord> visitRecordPack(String visitList, SellRecord sr) {
		List<VisitRecord> vrs=JSON.parseArray(visitList, VisitRecord.class);
		if(vrs!=null) {
			for (VisitRecord vr : vrs) {
				vr.setId(CorpdataUtil.getUUID());
				vr.setFkCustomer(sr.getFkCustomer());
				vr.setFkSellRecord(sr.getId());
				vr.setCreated(sr.getCreated());
			}
		}
		return vrs;
	}
	
	/**
	 * 直接将查询到的map数据放到ModelMap中 
	 * newAddcus 新增客户数
	 * win 新增赢单数
	 * lose 流失数
	 */
	@Override
	public void findCountByState(ModelMap map) {
		//月部分
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM");
		Date now=new Date();
		String date=sdf.format(now);
		Map<String, Integer> list = sellRecordMapper.selectCountByDate(date);
		if(list!=null) {
			list.put("newAddcus", findCountByDate(date));
			map.put("month", list);
		}
		
		//周部分
		sdf.applyPattern("yyyyww");
		date=sdf.format(now);
		list = sellRecordMapper.selectCountByDate(date);
		if(list!=null) {
			list.put("newAddcus", findCountByDate(date));
			map.put("week", list);
		}
		//跟进信息部分
		map.put("followSell", customerInfoMapper.selectFollow());
	}
	
	/**
	 * 根据创建日期统计客户个数
	 * @param date yyyy-MM
	 */
	@Override
	public int findCountByDate(String date) {
		return customerInfoMapper.findCountByDate(date);
	}

	@Override
	public List<Map<String,Object>> findCusByNamePhone(String param) {
		List<Map<String,Object>> list = customerInfoMapper.selectCusByNamePhone(param);
		return list;
	}
	
	@Override
	public List<CustomerInfo> findCustomerAll() {
		return mapper.selectAll(null);
	}

	/**
	 * 根据项目id查找项目分区
	 */
	@Override
	public List<Map<String, Object>> findPartitionByProject(String projectid) {
		return projectPartitionMapper.selectPartitionByProject(projectid,new Date());
	}

	/**
	 *   根据客户id删除客户和其相关信息
	 */
	@Override
	public Result delCustomerAll(String cusId) {
		//删除推荐房间记录
		int r = recommendRecordMapper.deleteByFkCustomer(cusId);
		//删除参观记录
		r=visitRecordMapper.deleteByFkCUstomer(cusId);
		//删除销售记录
		r=sellRecordMapper.deleteByFkCustomer(cusId);
		//删除销售团队人员
		r=sellTeamStaffMapper.deleteAllByCid(cusId);
		//删除客户
		r=customerInfoMapper.deleteById(cusId);
		
		return new Result(r, r>0?"删除成功":"未知错误");
	}
}
